<?php
trait CURD{

	public function getColumns(){
		return $this->db->query("show columns from ".$this->tableName)->fetchAll(PDO::FETCH_ASSOC);
	}

	public function formatListExtra($list){
		return $list;
	}

	public function afterDelete($item){

	}

	public function beforeSave($params){
		return $params;
	}

	public function afterSave($id,$params){

	}
	// 处理一些 时间范围 等特殊搜索
	public function processWhereExtra($where){

		return $where;
	}

	// 处理筛选参数 processWhere 接口
	public function processWhere($where){
		if($this->getRequest()->getQuery('keyword')){
			if(is_array($this->likeField)){
				if(count($this->likeField)){
					$or = [];
					foreach ($this->likeField as $value) {
						$or[$value.'[~]'] = $this->getRequest()->getQuery('keyword');
					}
					$where['OR'] = $or;
				}
			}else{
				$where[$this->likeField.'[~]'] = $this->getRequest()->getQuery('keyword');
			}
		}
		if($this->getRequest()->getQuery('sortProp') && $this->getRequest()->getQuery('sortType')){
			$where['ORDER']=[$this->getRequest()->getQuery('sortProp')=>$this->getRequest()->getQuery('sortType')];
		}

		$columns = $this->getColumns();
		$params = $this->getRequest()->getQuery();
		foreach ($columns as $value) {
			if(isset($params[$value['Field']]) && trim($params[$value['Field']]) !== ''){
				$where[$value['Field'].'[~]'] = $params[$value['Field']];
			}			
		}	
		$where = $this->processWhereExtra($where);
		return $where;
	}

	public function formatList($list){
		if(count($list)){
			foreach ($this->relations as $key => $value) {
				$ids = array_column($list, $key);
				$type = $value['type']??'one';
				$where = array_merge($value['where'],[$value['pri']=>$ids]);
				$data = indexBy($this->db->select($value['table'],$value['cols'],$where),$value['pri'],$type);
				foreach ($list as &$item) {
					$item[$value['as']] = $data[$item[$key]]??null;
				}
			}
		}
		return $list;
	}

	public function dictAction() {
		$where = [];
		if($this->isTree){
			$where[$this->parentKey] = 0;
		}
		$field = $this->likeField;
		if(is_array($this->likeField)){
			$field = $this->likeField[0];
		}
		if(!$this->deleted_at){
			$list = $this->db->select($this->tableName,['id',$field],$where);
		}else{
			$where['deleted_at'] = null;
			$list = $this->db->select($this->tableName,['id',$field],['deleted_at'=>null]);
		}	
		if($this->order){
			$where['ORDER'] = $this->order;
		}	
		foreach ($list as &$value) {
			$value['key'] = $value['id'];
			$value['title'] = $value[$field];
		}
		return success($list);
	}

	public function deleteAction() {
		$id = $this->getRequest()->getPost('id');
		$columns = $this->getColumns();
		$primaryKey = 'id';
		foreach ($columns as $value) {
			if($value['Key']=='PRI'){
				$primaryKey = $value['Field'];
			}			
		}	
		$item = $this->db->get($this->tableName,'*',[$primaryKey=>$id]);
		if(!$item){
			error('数据不存在');
		}
		$cols = array_column($columns,'Field');
		if(in_array('deleted_at',$cols)){
			$ret = $this->db->update($this->tableName,['deleted_at'=>date('Y-m-d H:i:s')],[$primaryKey=>$id]);
		}else{
			$ret = $this->db->delete($this->tableName,['id'=>$id]);
		}
		$count = $ret->rowCount();
		if($count){
			$this->afterDelete($item);
		}		
		success($count);
	}

	public function storeAction(){
		$columns = $this->getColumns();
		$primaryKey = 'id';
		$primaryVal = 0;		
		$req = $this->getRequest();
		$params = $req->getPost();
		$params = $this->beforeSave($params);
		unset($params['created_at']);
		unset($params['updated_at']);
		unset($params['deleted_at']);
		foreach ($columns as $value) {
			if($value['Key']=='PRI'){
				$primaryKey = $value['Field'];
				$primaryVal = $params[$value['Field']]??0;
				unset($params[$primaryKey]);
			}
			if(strpos($value['Type'], 'tinyint')!== false && isset($params[$value['Field']])){
				$params[$value['Field']] =  $params[$value['Field']]?1:0;
			}
		}	
		$cols = array_column($columns,'Field');
		foreach ($params as $key => $value) {
			if(!in_array($key, $cols)){
				unset($params[$key]);
			}
		}		
		if($primaryVal){
			if(in_array('updated_at', $cols)){
				$params['updated_at'] = date('Y-m-d H:i:s');
			}
			$this->db->update($this->tableName,$params,[$primaryKey=>$primaryVal]);
		}else{
			if(in_array('created_at', $cols)){
				$params['created_at'] = date('Y-m-d H:i:s');
			}
			$this->db->insert($this->tableName,$params);
			$primaryVal = $this->db->id();
		}
		$this->afterSave($primaryVal,$params);		
		success($params);
	}

	// 列表接口
	public function indexAction(){
		  if($this->isTree && !$this->getRequest()->getQuery('keyword') && count($this->getRequest()->getQuery()) < 6){
		  	return $this->renderTree();
		  }
		  $page = $this->getRequest()->getQuery('page',1); 
	      $size = $this->getRequest()->getQuery('size',10); 
	      $from = ($page - 1)*$size;  
	      $count = 0;
	      $list = [];
	      $where = ['deleted_at'=>null,'ORDER'=>['id'=>'DESC']];
	      if(!$this->deleted_at){
	      	unset($where['deleted_at']);
	      }
	      if($this->order){
	      	$where['ORDER'] = $this->order;
	      }
	      $where = $this->processWhere($where);
	      $count = $this->db->count($this->tableName,$where);
	      $where = array_merge($where,['LIMIT'=>[$from,$size]]);
	      $list = $this->db->select($this->tableName,"*",$where);
	      $list = $this->formatList($list);
	      $list = $this->formatListExtra($list);
	      $pages = ceil($count/$size);
	      $pagination = ['page'=>$page,'size'=>$size,'total'=>$count];
	      success(compact('list','pagination'));
	}

	private function renderTree(){
		  $where = ['deleted_at'=>null,'ORDER'=>['id'=>'DESC']];
	      if(!$this->deleted_at){
	      	unset($where['deleted_at']);
	      }
	      if($this->order){
	      	$where['ORDER'] = $this->order;
	      }
	      $where = $this->processWhere($where);
	      $list = $this->db->select($this->tableName,"*",$where);
	      $list = $this->formatList($list);
	      $list = $this->formatListExtra($list);
	      $list = getTreeChildren($list,$this->parentKey);
	      $pagination = ['page'=>1,'size'=>10000,'total'=>0];
	      success(compact('list','pagination'));
	}

}
?>